import { useState, useEffect } from "react";
import { useDispatch } from "react-redux";
import {
  Modal,
  Radio,
  Form,
  Input,
  Button,
  Row,
  Col,
  Checkbox,
  message,
} from "antd";
import { initUserInfo, changeLoginStatus } from "../redux/userSlice";
import {
  getCaptcha,
  userIsExist,
  addUser,
  userLogin,
  getUserById,
} from "../api/user";

import styles from "../css/LoginForm.module.css";

function LoginForm(props) {
  // 表单类型，1为登录，2为注册
  const [formType, setFormType] = useState(1);
  // 验证码
  const [captcha, setCaptcha] = useState(null);
  const [loginForm] = Form.useForm();
  const [registerForm] = Form.useForm();
  const dispatch = useDispatch();

  // 切换表单类型
  function handleChangeFormType(e) {
    setFormType(e.target.value);
    handleClickCaptcha();
  }

  // 切换验证码
  async function handleClickCaptcha() {
    const result = await getCaptcha();
    setCaptcha(result);
  }
  /**
   * 验证登录账号是否存在
   */
  async function checkLoginIdIsExist(_, value) {
    if (value) {
      const { data } = await userIsExist(value);
      if (data) {
        // 该 loginId 已经注册过了
        return Promise.reject("该用户已经注册过了");
      }
    }
  }

  // 登录
  async function handleLogin(loginInfo) {
    const result = await userLogin(loginInfo);
    if (result.data) {
      // 验证码是正确的
      // 接下来会有这么几种情况 （1）密码不正确 （2）账户被冻结 （3）账户正常，能够正常登录
      const data = result.data;
      if (!data.data) {
        // 账号密码不正确
        message.error("账号或密码不正确");
        handleClickCaptcha();
      } else if (!data.data.enabled) {
        // 账号被禁用了
        message.warning("账号被禁用，请联系管理员");
        handleClickCaptcha();
      } else {
        // 说明账号密码正确，能够登录
        // 存储 token
        localStorage.userToken = data.token;
        // 将用户的信息存储到状态仓库，方便后面使用
        const result = await getUserById(data.data._id);
        dispatch(initUserInfo(result.data));
        dispatch(changeLoginStatus(true));
        handleClose();
      }
    } else {
      message.warning(result.msg);
      handleClickCaptcha();
    }
  }
  // 注册
  async function handleRegister(registerInfo) {
    // TODO：希望能直接想addUser传入registerInfo
    // 原因：Ant Design 的 Form 组件通过 name 属性标识字段的唯一性
    // 即使属于不同 Form 实例，默认情况下它们会共享同一份数据​​，导致视图和数据的联动更新
    // 这里表格basic1和basic2 下面name为loginId的Item会联动，所以第二表要改为registerId
    const result = await addUser({
      loginId: registerInfo.registerId,
      nickname: registerInfo.nickname,
      captcha: registerInfo.registerCaptcha,
    });
    if (result.data) {
      message.success("用户注册成功，默认密码为 123456");
      // 还需要将用户的信息存储到数据仓库里面
      dispatch(initUserInfo(result.data));
      // 将数据仓库的登录状态进行修改
      dispatch(changeLoginStatus(true));
      // 关闭登录注册的弹出框
      handleClose();
    } else {
      message.warning(result.msg);
      handleClickCaptcha();
    }
  }

  // 清空上一次的内容，并关闭弹窗
  function handleClose() {
    registerForm.resetFields();
    loginForm.resetFields();
    props.closeModal();
  }

  useEffect(() => {
    handleClickCaptcha();
  }, [props.isShow]);

  let container = null;
  if (formType === 1) {
    // 登录面板的 JSX
    container = (
      <div className={styles.container}>
        <Form
          name="basic1"
          autoComplete="off"
          onFinish={handleLogin}
          form={loginForm}
          initialValues={{
            loginId: "",
            loginPwd: "",
            captcha: "",
            remember: false,
          }}
        >
          <Form.Item
            label="账号"
            name="loginId"
            rules={[
              {
                required: true,
                message: "请输入账号",
              },
            ]}
            validateTrigger="onBlur"
          >
            <Input placeholder="请输入你的账号" />
          </Form.Item>

          <Form.Item
            label="密码"
            name="loginPwd"
            rules={[
              {
                required: true,
                message: "请输入密码",
              },
            ]}
            validateTrigger="onBlur"
          >
            <Input.Password placeholder="请输入你的登录密码，新用户默认为123456" />
          </Form.Item>

          {/* 验证码 */}
          <Form.Item
            name="captcha"
            label="验证码"
            rules={[
              {
                required: true,
                message: "请输入验证码",
              },
            ]}
            validateTrigger="onBlur"
          >
            <Row align="middle">
              <Col span={16}>
                <Input placeholder="请输入验证码" />
              </Col>
              <Col span={6}>
                <div
                  className={styles.captchaImg}
                  onClick={handleClickCaptcha}
                  dangerouslySetInnerHTML={{ __html: captcha }}
                ></div>
              </Col>
            </Row>
          </Form.Item>

          <Form.Item
            name="remember"
            valuePropName="checked"
            wrapperCol={{
              offset: 5,
              span: 16,
            }}
          >
            <Checkbox>记住我</Checkbox>
          </Form.Item>

          <Form.Item
            wrapperCol={{
              offset: 5,
              span: 16,
            }}
          >
            <Button
              type="primary"
              htmlType="submit"
              style={{ marginRight: 20 }}
            >
              登录
            </Button>
            <Button type="primary" htmlType="reset">
              重置
            </Button>
          </Form.Item>
        </Form>
      </div>
    );
  } else {
    // 注册面板的 JSX
    container = (
      <div className={styles.container}>
        <Form
          name="basic2"
          autoComplete="off"
          onFinish={handleRegister}
          form={registerForm}
          initialValues={{
            registerId: "",
            nickname: "",
            registerCaptcha: "",
          }}
        >
          <Form.Item
            label="账号"
            name="registerId"
            rules={[
              {
                required: true,
                message: "请输入账号，仅此项为必填项",
              },
              // 验证用户是否已经存在
              { validator: checkLoginIdIsExist },
            ]}
            validateTrigger="onBlur"
          >
            <Input placeholder="请输入账号" />
          </Form.Item>

          <Form.Item label="用户昵称" name="nickname">
            <Input placeholder="请输入昵称，不填写默认为新用户xxx" />
          </Form.Item>

          <Form.Item
            name="registerCaptcha"
            label="验证码"
            rules={[
              {
                required: true,
                message: "请输入验证码",
              },
            ]}
            validateTrigger="onBlur"
          >
            <Row align="middle">
              <Col span={16}>
                <Input placeholder="请输入验证码" />
              </Col>
              <Col span={6}>
                <div
                  className={styles.captchaImg}
                  onClick={handleClickCaptcha}
                  dangerouslySetInnerHTML={{ __html: captcha }}
                ></div>
              </Col>
            </Row>
          </Form.Item>

          <Form.Item
            wrapperCol={{
              offset: 5,
              span: 16,
            }}
          >
            <Button
              type="primary"
              htmlType="submit"
              style={{ marginRight: 20 }}
            >
              注册
            </Button>
            <Button type="primary" htmlType="reset">
              重置
            </Button>
          </Form.Item>
        </Form>
      </div>
    );
  }
  return (
    <div>
      <Modal
        title="注册/登录"
        open={props.isShow}
        // onOk={handleOk}
        onCancel={handleClose}
        footer={null}
      >
        <Radio.Group
          value={formType}
          onChange={handleChangeFormType}
          className={styles.radioGroup}
          buttonStyle="solid"
        >
          <Radio.Button value={1} className={styles.radioButton}>
            登录
          </Radio.Button>
          <Radio.Button value={2} className={styles.radioButton}>
            注册
          </Radio.Button>
        </Radio.Group>
        {/* 下面需要显示对应功能的表单 */}
        {container}
      </Modal>
    </div>
  );
}

export default LoginForm;
